<template>
  <div class="dynamic-form" :class="config.className" :style="config.style">
    <a-form
      ref="formRef"
      :model="formModel"
      :layout="config.layout || 'horizontal'"
      :label-col="config.labelCol || { span: 8 }"
      :wrapper-col="config.wrapperCol || { span: 16 }"
      :size="config.size || 'middle'"
      :colon="config.colon !== false"
      :label-align="config.labelAlign || 'right'"
      @finish="handleSubmit"
    >
      <!-- 动态渲染表单字段 -->
      <template v-for="field in showFields" :key="field.field">
        <component
          :is="getFieldComponent(field.type)"
          :field="field"
          :model="formModel"
          :value="formModel[field.field]"
          :disabled="disabled"
          :readonly="readonly"
          @update:value="(value) => handleFieldChange(field, value)"
          @change="(value) => handleFieldChange(field, value)"
          @blur="(value) => handleFieldBlur(field, value)"
          @focus="(value) => handleFieldFocus(field, value)"
        />
      </template>

      <!-- 表单操作按钮 -->
      <a-form-item v-if="showActions" :wrapper-col="{ offset: 8, span: 16 }">
        <slot name="actions" :form="formMethods">
          <a-button
            type="primary"
            :loading="formState.submitting"
            @click="handleSubmit"
          >
            提交
          </a-button>
          <a-button style="margin-left: 8px" @click="handleReset">
            重置
          </a-button>
        </slot>
      </a-form-item>
    </a-form>
  </div>
</template>

<script setup>
import { computed, watch, nextTick } from 'vue'
import { getFieldComponent } from '../field-map'
import { useDynamicForm } from '../useDynamicForm'

const props = defineProps({
  // 表单配置
  schema: {
    type: Array,
    required: true
  },
  // 表单数据
  model: {
    type: Object,
    default: () => ({})
  },
  // 表单配置
  config: {
    type: Object,
    default: () => ({})
  },
  // 是否禁用
  disabled: {
    type: Boolean,
    default: false
  },
  // 是否只读
  readonly: {
    type: Boolean,
    default: false
  },
  // 是否显示操作按钮
  showActions: {
    type: Boolean,
    default: true
  }
})

const emit = defineEmits([
  'update:model',
  'change',
  'submit',
  'reset',
  'validate',
  'field-change',
  'field-blur',
  'field-focus'
])

// 使用动态表单hook
const {
  formModel,
  formRef,
  formState,
  visibleFields,
  showFields,
  handleFieldChange: hookHandleFieldChange,
  validate,
  submit,
  reset,
  setFieldValue,
  getFieldValue,
  setFieldsValue,
  getFieldsValue,
  clearField,
  clearFields
} = useDynamicForm({
  schema: props.schema,
  model: props.model,
  config: props.config,
  events: {
    onChange: (field, value, model) => {
      emit('field-change', field, value, model)
      emit('change', model)
      emit('update:model', model)
    },
    onBlur: (field, value, model) => {
      emit('field-blur', field, value, model)
    },
    onFocus: (field, value, model) => {
      emit('field-focus', field, value, model)
    },
    onSubmit: (values) => {
      emit('submit', values)
    },
    onReset: (model) => {
      emit('reset', model)
      emit('update:model', model)
    },
    onValidate: (valid, errors) => {
      emit('validate', valid, errors)
    }
  }
})

// 表单方法集合
const formMethods = {
  validate,
  submit,
  reset,
  setFieldValue,
  getFieldValue,
  setFieldsValue,
  getFieldsValue,
  clearField,
  clearFields
}

// 处理字段变化
const handleFieldChange = (field, value) => {
  hookHandleFieldChange(field, value)
}

// 处理字段失焦
const handleFieldBlur = (field, value) => {
  emit('field-blur', field.field, value, formModel.value)
}

// 处理字段聚焦
const handleFieldFocus = (field, value) => {
  emit('field-focus', field.field, value, formModel.value)
}

// 处理表单提交
const handleSubmit = async () => {
  const result = await submit()
  if (result.success) {
    emit('submit', result.data)
  }
}

// 处理表单重置
const handleReset = () => {
  reset()
}

// 监听外部model变化
watch(() => props.model, (newModel) => {
  Object.assign(formModel.value, newModel)
}, { deep: true })

// 暴露方法给父组件
defineExpose({
  ...formMethods,
  formRef,
  formModel
})
</script>

<style scoped>
.dynamic-form {
  width: 100%;
}

.dynamic-form :deep(.ant-form-item) {
  margin-bottom: 16px;
}

.dynamic-form :deep(.ant-form-item-label) {
  text-align: left;
}

.dynamic-form :deep(.ant-form-item-explain-error) {
  font-size: 12px;
}
</style> 